PythonでS3上の自作モジュールをスクリプト中で動的にインポートしてみる
はじめに
データアナリティクス事業本部のkobayashiです。
Pythonの自作モジュールを使う際にPythonの実行環境の制約によりあらかじめ自作モジュールを実行環境へ置いておくことができなかったり、パッケージにしてpipでインストールできない場面において、S3上に自作モジュールをアップロードしてその自作モジュールをスクリプト中でインポートする方法を調べたのでまとめます。
S3上のファイルをモジュールとして読み込む
S3上のファイルを読み込む方法を色々調べましたがなかなか最適解が見つからず同じような情報としては以下の記事しか見つかりませんでした。
- amazon s3 - Import python module from external url - Stack Overflow
- python - import module from s3 in sagemaker - Stack Overflow
- jupyter notebook - Importing .py files in Google Colab - Stack Overflow
上記の情報を参考にちょっと回りくどいのですが以下のアプローチで実現しました。
- tempfileモジュールで一時ディレクトリを作成する
- 一時ディレクトリを
sys.path.append
でパスを通す - S3からBoto3で自作のモジュールを一時ディレクトリにダウンロードする
- importlibでモジュールを動的にインポートする
コードの解説と動的インポートの実行
では実際に自作モジュールを作成してからS3にアップロードして実行時に読み込んみます。
はじめにモジュールファイルは以下のように四則を行う関数としています。
def add(x, y): return x + y def sub(x, y): return x - y def mul(x, y): return x * y def div(x, y): return x / y
これを予めS3にアップロードしておきます。
次に今回のメインテーマであるS3上の自作モジュールを読み込んで使用するスクリプトは以下のようになります。
import importlib import sys import tempfile import boto3 s3 = boto3.client("s3") # 独自モジュール読み込み with tempfile.TemporaryDirectory(dir="/tmp/", prefix="md_") as tmpdir: sys.path.append(tmpdir) s3.download_file( "my-sample-backet", # バケット名 "mypackage/mymodule.py", # 自作モジュールのパス tmpdir + "/mymodule.py", ) mymodule = importlib.import_module("mymodule") # モジュールの使用 print(mymodule.add(3, 2)) print(mymodule.sub(3, 2)) print(mymodule.mul(3, 2)) print(mymodule.div(3, 2))
コードを解説します。
- 1-5行目までは独自モジュールを読み込むために必要なモジュールをインポートしています。
- 10行目ではtempfileモジュールを使って一時ディレクトリ作成しています。
- 11行目で一時ディレクトリのパスを通しています。
- 12-16行目でS3上の独自モジュールを一時ディレクトリにダウンロードします。
- 17行目でimportlibモジュールを使ってダウンロードしたモジュールをインポートしています。
これでS3上の独自モジュールを読み込んでスクリプト内で実行できるようになります。上記のコードを実行してみると以下のような出力になります。
$ python main.py 5 1 6 1.5
まとめ
S3上にアップロードしたPythonの自作モジュールをスクリプト中でインポートする方法をまとめました。限られた実行環境での使用となりますが、同じような環境で悩んでいる人がいたら是非参考にしてください。
最後まで読んで頂いてありがとうございました。~~